package org.hako.recite.word.review;

import java.awt.Container;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

import org.hako.recite.word.gui.swing.AbstractReciteWordFrame;
import org.hako.recite.word.model.Word;
import org.hako.recite.word.util.StringUtils;

/**
 * Frame of word review.
 * 
 * @since 0.4.10
 * @author <a href="mailto:xnnyygn@gmail.com">xnnyygn</a>
 */
public class WordReviewFrame extends AbstractReciteWordFrame {

	private ReviewWordsProvider provider;
	private int currentIndex;
	private JTextArea taWord;
	private JButton btnPrevious;
	private JButton btnNext;
	private JLabel lbWordCounter;

	/**
	 * Create
	 * 
	 * @param provider
	 */
	public WordReviewFrame(ReviewWordsProvider provider) {
		this(provider, 0);
	}

	/**
	 * Create
	 * 
	 * @param provider
	 * @param startIndex
	 */
	public WordReviewFrame(ReviewWordsProvider provider, int startIndex) {
		super("Word Review");
		this.provider = provider;
		exitOnClose();
		JPanel panel = new JPanel(new GridBagLayout());
		panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
		addComponentsToPane(panel);
		frame.add(panel);
		frame.setSize(400, 300);
		safelySetCurrentIndex(startIndex);
		showWord(currentIndex);
		
		// center in the monitor
		centerInScreen();
	}

	/**
	 * Safely set current index.
	 * 
	 * @param startIndex
	 */
	private void safelySetCurrentIndex(int startIndex) {
		int wordCount = provider.getCount();
		if (startIndex < 0) {
			startIndex = -startIndex;
		}
		currentIndex = startIndex >= wordCount ? wordCount - 1 : startIndex;
	}

	/**
	 * Add component to pane.
	 * 
	 * @param container
	 */
	private void addComponentsToPane(Container container) {
		GridBagConstraints c = new GridBagConstraints();
		c.gridx = 0;
		c.gridy = 0;
		c.gridwidth = 4;
		c.fill = GridBagConstraints.HORIZONTAL;
		lbWordCounter = new JLabel("Word 1/100");
		container.add(lbWordCounter, c);

		c.gridy = 1;
		c.weighty = 1.0d;
		c.fill = GridBagConstraints.BOTH;
		c.insets = new Insets(10, 0, 10, 0);
		taWord = new JTextArea();
		// taWord.setEditable(false);
		JScrollPane scrollPane = new JScrollPane(taWord,
				JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
				JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
		container.add(scrollPane, c);

		c.gridy = 2;
		c.weighty = 0.0d;
		c.weightx = 0.33d;
		c.gridwidth = 1;
		c.fill = GridBagConstraints.HORIZONTAL;
		c.insets = new Insets(0, 0, 0, 10);
		JButton btnExit = new JButton("Exit");
		btnExit.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				System.exit(0);
			}
		});
		container.add(btnExit, c);

		c.gridx = 1;
		JButton btnJump = new JButton("Jump to ...");
		btnJump.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				String jumpToIndex = JOptionPane.showInputDialog(
						"Please input index(1~" + provider.getCount() + "):",
						String.valueOf(currentIndex + 1));
				if (!StringUtils.isBlank(jumpToIndex)) {
					safelySetCurrentIndex(Integer.parseInt(jumpToIndex) - 1);
					showWord(currentIndex);
				}
			}
		});
		container.add(btnJump, c);

		c.gridx = 2;
		btnPrevious = new JButton("Previous");
		btnPrevious.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				showPreviousWord();
			}
		});
		container.add(btnPrevious, c);

		c.gridx = 3;
		c.insets = new Insets(0, 0, 0, 0);
		btnNext = new JButton("Next");
		btnNext.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				showNextWord();
			}
		});
		container.add(btnNext, c);
	}

	/**
	 * Show word.
	 * 
	 * @param index
	 */
	private void showWord(int index) {
		updateWordCounter(index);
		updateWord(index);
		updateButtons(index);
	}

	/**
	 * Update buttons.
	 * 
	 * @param index
	 */
	private void updateButtons(int index) {
		btnPrevious.setEnabled((index != 0));
		btnNext.setEnabled(index + 1 < provider.getCount());
	}

	/**
	 * Update word.
	 * 
	 * @param index
	 */
	private void updateWord(int index) {
		String[] columnTitles = provider.getColumnTitles();
		int columnCount = columnTitles.length;
		Word word = provider.get(index);
		StringBuilder builder = new StringBuilder();
		for (int i = 0; i < columnCount; i++) {
			builder.append(columnTitles[i]);
			builder.append(": ");
			builder.append(word.get(i));
			builder.append('\n');
		}
		taWord.setText(builder.toString());
	}

	/**
	 * Update word counter.
	 * 
	 * @param index
	 */
	private void updateWordCounter(int index) {
		StringBuilder builder = new StringBuilder("Word ");
		builder.append(index + 1);
		builder.append('/');
		builder.append(provider.getCount());
		lbWordCounter.setText(builder.toString());
	}

	/**
	 * Show previous word.
	 */
	private void showPreviousWord() {
		currentIndex--;
		showWord(currentIndex);
	}

	/**
	 * Show next word.
	 */
	private void showNextWord() {
		currentIndex++;
		showWord(currentIndex);
	}
}
